use std::process::{Command, Child, Stdio};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::thread;
use anyhow::{anyhow, Result};
use tauri::{AppHandle};
use crate::rand_str::generate_random_string; // 导入生成随机字符串函数

// 完整关闭URL（字面量）
const SHUTDOWN_URL: &str = "http://localhost:50407/secure/shutdown";  // 完整关闭URL（字面量）

pub struct JavaProcess {
    // 公开字段（关键修改）
    pub java_bin: String,
    pub jar_path: String,
    pub shutdown_key: String,  // 新增：前端关闭接口地址
    app_handle: Option<AppHandle>,     // 新增：Tauri 应用句柄（用于调用前端）
    child: Arc<Mutex<Option<Child>>>,  // 保持私有（不需要测试直接访问）
}

impl JavaProcess {
    /// 创建新的 Java 进程管理器（新增 app_handle 参数）
    pub fn new(
        java_bin: String,
        jar_path: String,
        app_handle: Option<AppHandle>, // 新增：传递 Tauri 应用句柄
    ) -> Self {
        JavaProcess {
            java_bin,
            jar_path,
            shutdown_key: generate_random_string(), // 生成随机字符串作为关闭密钥
            app_handle, // 保存 Tauri 应用句柄
            child: Arc::new(Mutex::new(None)),
        }
    }

    /// 启动 Java 进程
    pub fn start(&self) -> Result<()> {
        let mut child_guard = self.child.lock().map_err(|e| anyhow!("锁错误: {}", e))?;
        
        // 如果已有进程在运行，先停止它
        if let Some(mut child) = child_guard.take() {
            println!("ℹ️ 检测到旧进程，尝试停止（PID: {:?}）", child.id());  // 新增：打印旧进程PID
            self.stop_nolock(&mut child)?;  // 处理 stop_nolock 的错误
        }
    
        // 分步构建 Command 实例
        let mut command = Command::new(&self.java_bin);
        command.arg("-jar");
        command.arg(&self.jar_path);
        command.arg(format!("--shutdown.key={}",&self.shutdown_key));
        command.stdout(Stdio::inherit());
        command.stderr(Stdio::inherit());

        // 关键检查：捕获 spawn 错误并打印
        let child = command.spawn().map_err(|e| {
            println!("❌ 启动 Java 进程失败: {}", e);
            anyhow!("spawn 失败: {}", e)
        })?;
        let pid = child.id();  // 获取新进程PID
        *child_guard = Some(child);
        println!("✅ Java 应用已启动（PID: {}）: {} -jar {} --shutdown.key={}", pid, self.java_bin, self.jar_path, self.shutdown_key);  // 新增PID日志
        Ok(())
    }

    pub fn stop(&self) -> Result<()> {
        let mut child_guard = self.child.lock().map_err(|e| anyhow!("锁错误: {}", e))?;
        if let Some(mut child) = child_guard.take() {
            self.stop_nolock(&mut child)?;  // 传播 stop_nolock 的错误
            println!("🛑 Java 应用已停止");
        } else {
            println!("⚠️ 尝试停止未运行的 Java 应用");
        }
        Ok(())
    }

    // 修正返回类型为 Result
    fn stop_nolock(&self, child: &mut Child) -> Result<()> {
        let pid = child.id();
        println!("ℹ️ 开始停止进程（PID: {}）", pid);

        // 发送关闭请求
        let _ = tokio::runtime::Runtime::new()
            .expect("创建 Tokio 运行时失败")
            .block_on(self.send_close_request());

        // 新增：每0.5秒检查一次，最多等待3秒
        let start_time = std::time::Instant::now();
        let max_wait = Duration::from_secs(3);
        let check_interval = Duration::from_millis(200);

        loop {
            // 检查是否超时
            if start_time.elapsed() >= max_wait {
                println!("⏰ 等待3秒超时，进程未主动退出");
                break;
            }

            // 检查进程是否已退出
            match child.try_wait()? {
                Some(_) => {
                    println!("✅ 进程已主动退出");
                    return Ok(());
                }
                None => {
                    println!("⏳ 进程仍在运行，等待0.5秒后重试...");
                    thread::sleep(check_interval);
                }
            }
        }

        // 超时后强制终止
        println!("⚠️ 强制终止 Java 进程");
        child.kill().map_err(|e| anyhow!("强制终止失败: {}", e))?;
        Ok(())
    }

    // 修改返回类型为 Result<()>（添加错误处理）
    async fn send_close_request(&self) -> Result<()> {
        let resp = reqwest::get(format!("{}?key={}", SHUTDOWN_URL, self.shutdown_key)).await?;
        println!("关闭请求响应状态码: {}", resp.status());
        Ok(())
    }
}